"""
数据转换工具模块

本文件提供平板端数据到存储端数据格式的转换功能，主要用于：
1. 将平板端的TabletBrainWaveData转换为CloudStorageEEGData格式
2. 处理时间戳排序和数据包序列号生成
3. 支持MNE和YASA处理后的数据格式转换
4. 确保数据在传输过程中保持有序

使用方法：
- TabletToStorageConverter: 主要转换器类
- convert_tablet_data_batch: 批量转换平板端数据
- generate_storage_format: 生成存储端格式数据

原理：
通过时间戳对原始数据进行排序，生成有序的frames数组。
为每个数据包分配序列号，确保在网络传输中数据包不会乱序。
支持MNE过滤和YASA分析后的数据格式，保持时间戳信息的完整性。
"""

from typing import List, Dict, Any, Optional, Tuple
from datetime import datetime
import time
import logging

from ..models.tablet_data_models import TabletBrainWaveData, RawValuePoint
from ..models.cloud_storage_models import (
    CloudStorageEEGData, 
    WaveData, 
    WaveFrames, 
    FrequencyBandData
)
from ..models.brain_wave_data import BrainWaveData, TimeSeriesData, FrequencyData

logger = logging.getLogger(__name__)


class TabletToStorageConverter:
    """平板端数据到存储端数据格式转换器"""
    
    def __init__(self):
        """初始化转换器"""
        self.sequence_counter = 0
        self.last_timestamp = 0
    
    def convert_tablet_data_batch(
        self, 
        tablet_data_list: List[TabletBrainWaveData],
        duration_seconds: float = 10.0
    ) -> CloudStorageEEGData:
        """
        批量转换平板端数据为存储端格式
        
        Args:
            tablet_data_list: 平板端数据列表
            duration_seconds: 数据包时长（秒）
            
        Returns:
            CloudStorageEEGData: 存储端格式数据
        """
        if not tablet_data_list:
            raise ValueError("平板端数据列表不能为空")
        
        # 使用第一个数据包的基本信息
        first_data = tablet_data_list[0]
        
        # 收集所有原始数据点并按时间戳排序
        all_raw_points = []
        for data in tablet_data_list:
            all_raw_points.extend(data.rawValue)
        
        # 按时间戳排序确保数据有序
        all_raw_points.sort(key=lambda x: x.timestamp)
        
        # 提取有序的原始数据值
        raw_values = [point.value for point in all_raw_points]
        
        # 生成过滤后的数据（这里简化处理，实际应该通过MNE处理）
        filtered_values = self._apply_simple_filter(raw_values)
        
        # 收集频段数据
        frequency_data = self._collect_frequency_data(tablet_data_list)
        
        # 生成序列号
        self.sequence_counter += 1
        
        # 计算数据时间戳
        data_timestamp = time.time()
        
        # 构建存储端格式数据
        storage_data = CloudStorageEEGData(
            id=first_data.id,
            room_id=first_data.roomId,
            data_timestamp=data_timestamp,
            duration_seconds=duration_seconds,
            sequence_number=self.sequence_counter,
            eeg_wave_data=WaveData(
                frame_rate=512,  # 假设512Hz采样率
                wave=WaveFrames(frames=raw_values),
                filtered=WaveFrames(frames=filtered_values)
            ),
            delta_data=FrequencyBandData(
                frame_rate=1,  # 频段数据通常1Hz
                wave=WaveFrames(frames=frequency_data['delta']),
                filtered=WaveFrames(frames=frequency_data['delta'])
            ),
            theta_data=FrequencyBandData(
                frame_rate=1,
                wave=WaveFrames(frames=frequency_data['theta']),
                filtered=WaveFrames(frames=frequency_data['theta'])
            ),
            low_alpha_data=FrequencyBandData(
                frame_rate=1,
                wave=WaveFrames(frames=frequency_data['low_alpha']),
                filtered=WaveFrames(frames=frequency_data['low_alpha'])
            ),
            high_alpha_data=FrequencyBandData(
                frame_rate=1,
                wave=WaveFrames(frames=frequency_data['high_alpha']),
                filtered=WaveFrames(frames=frequency_data['high_alpha'])
            ),
            low_beta_data=FrequencyBandData(
                frame_rate=1,
                wave=WaveFrames(frames=frequency_data['low_beta']),
                filtered=WaveFrames(frames=frequency_data['low_beta'])
            ),
            high_beta_data=FrequencyBandData(
                frame_rate=1,
                wave=WaveFrames(frames=frequency_data['high_beta']),
                filtered=WaveFrames(frames=frequency_data['high_beta'])
            ),
            low_gamma_data=FrequencyBandData(
                frame_rate=1,
                wave=WaveFrames(frames=frequency_data['low_gamma']),
                filtered=WaveFrames(frames=frequency_data['low_gamma'])
            ),
            mid_gamma_data=FrequencyBandData(
                frame_rate=1,
                wave=WaveFrames(frames=frequency_data['mid_gamma']),
                filtered=WaveFrames(frames=frequency_data['mid_gamma'])
            )
        )
        
        logger.info(f"转换完成：会话{first_data.id}，序列号{self.sequence_counter}，数据点{len(raw_values)}个")
        return storage_data
    
    def convert_brain_wave_data_with_timestamps(
        self,
        brain_wave_data: BrainWaveData,
        session_id: str,
        room_id: str,
        raw_timestamps: Optional[List[int]] = None
    ) -> CloudStorageEEGData:
        """
        转换BrainWaveData（MNE/YASA处理后）为存储端格式，保持时间戳信息
        
        Args:
            brain_wave_data: MNE/YASA处理后的脑波数据
            session_id: 会话ID
            room_id: 房间ID
            raw_timestamps: 原始数据的时间戳列表
            
        Returns:
            CloudStorageEEGData: 存储端格式数据
        """
        # 生成序列号
        self.sequence_counter += 1
        
        # 计算数据时间戳和时长
        data_timestamp = time.time()
        if brain_wave_data.time_data and len(brain_wave_data.time_data.values) > 0:
            duration_seconds = len(brain_wave_data.time_data.values) / 512.0  # 假设512Hz
        else:
            duration_seconds = 10.0  # 默认10秒
        
        # 提取时域数据
        raw_values = brain_wave_data.time_data.values if brain_wave_data.time_data else []
        filtered_values = self._apply_simple_filter(raw_values) if raw_values else []
        
        # 提取频域数据
        frequency_frames = {}
        if brain_wave_data.frequency_data:
            freq_data = brain_wave_data.frequency_data
            frequency_frames = {
                'delta': [freq_data.delta],
                'theta': [freq_data.theta],
                'low_alpha': [freq_data.low_alpha],
                'high_alpha': [freq_data.high_alpha],
                'low_beta': [freq_data.low_beta],
                'high_beta': [freq_data.high_beta],
                'low_gamma': [freq_data.low_gamma],
                'mid_gamma': [freq_data.mid_gamma]
            }
        else:
            # 默认频段数据
            frequency_frames = {
                'delta': [0.0], 'theta': [0.0], 'low_alpha': [0.0], 'high_alpha': [0.0],
                'low_beta': [0.0], 'high_beta': [0.0], 'low_gamma': [0.0], 'mid_gamma': [0.0]
            }
        
        # 构建存储端格式数据
        storage_data = CloudStorageEEGData(
            id=session_id,
            room_id=room_id,
            data_timestamp=data_timestamp,
            duration_seconds=duration_seconds,
            sequence_number=self.sequence_counter,
            eeg_wave_data=WaveData(
                frame_rate=512,
                wave=WaveFrames(frames=raw_values),
                filtered=WaveFrames(frames=filtered_values)
            ),
            delta_data=FrequencyBandData(
                frame_rate=1,
                wave=WaveFrames(frames=frequency_frames['delta']),
                filtered=WaveFrames(frames=frequency_frames['delta'])
            ),
            theta_data=FrequencyBandData(
                frame_rate=1,
                wave=WaveFrames(frames=frequency_frames['theta']),
                filtered=WaveFrames(frames=frequency_frames['theta'])
            ),
            low_alpha_data=FrequencyBandData(
                frame_rate=1,
                wave=WaveFrames(frames=frequency_frames['low_alpha']),
                filtered=WaveFrames(frames=frequency_frames['low_alpha'])
            ),
            high_alpha_data=FrequencyBandData(
                frame_rate=1,
                wave=WaveFrames(frames=frequency_frames['high_alpha']),
                filtered=WaveFrames(frames=frequency_frames['high_alpha'])
            ),
            low_beta_data=FrequencyBandData(
                frame_rate=1,
                wave=WaveFrames(frames=frequency_frames['low_beta']),
                filtered=WaveFrames(frames=frequency_frames['low_beta'])
            ),
            high_beta_data=FrequencyBandData(
                frame_rate=1,
                wave=WaveFrames(frames=frequency_frames['high_beta']),
                filtered=WaveFrames(frames=frequency_frames['high_beta'])
            ),
            low_gamma_data=FrequencyBandData(
                frame_rate=1,
                wave=WaveFrames(frames=frequency_frames['low_gamma']),
                filtered=WaveFrames(frames=frequency_frames['low_gamma'])
            ),
            mid_gamma_data=FrequencyBandData(
                frame_rate=1,
                wave=WaveFrames(frames=frequency_frames['mid_gamma']),
                filtered=WaveFrames(frames=frequency_frames['mid_gamma'])
            )
        )
        
        logger.info(f"转换BrainWaveData完成：会话{session_id}，序列号{self.sequence_counter}")
        return storage_data
    
    def _apply_simple_filter(self, raw_values: List[float]) -> List[float]:
        """
        应用简单的滤波处理（占位符，实际应该使用MNE处理）
        
        Args:
            raw_values: 原始数据值
            
        Returns:
            List[float]: 过滤后的数据值
        """
        if not raw_values:
            return []
        
        # 简单的移动平均滤波
        filtered = []
        window_size = 3
        
        for i in range(len(raw_values)):
            start_idx = max(0, i - window_size // 2)
            end_idx = min(len(raw_values), i + window_size // 2 + 1)
            avg_value = sum(raw_values[start_idx:end_idx]) / (end_idx - start_idx)
            filtered.append(avg_value)
        
        return filtered
    
    def _collect_frequency_data(self, tablet_data_list: List[TabletBrainWaveData]) -> Dict[str, List[float]]:
        """
        收集频段数据
        
        Args:
            tablet_data_list: 平板端数据列表
            
        Returns:
            Dict[str, List[float]]: 各频段数据
        """
        frequency_data = {
            'delta': [],
            'theta': [],
            'low_alpha': [],
            'high_alpha': [],
            'low_beta': [],
            'high_beta': [],
            'low_gamma': [],
            'mid_gamma': []
        }
        
        for data in tablet_data_list:
            frequency_data['delta'].append(float(data.delta))
            frequency_data['theta'].append(float(data.theta))
            frequency_data['low_alpha'].append(float(data.lowAlpha))
            frequency_data['high_alpha'].append(float(data.highAlpha))
            frequency_data['low_beta'].append(float(data.lowBeta))
            frequency_data['high_beta'].append(float(data.highBeta))
            frequency_data['low_gamma'].append(float(data.lowGamma))
            frequency_data['mid_gamma'].append(float(data.midGamma))
        
        return frequency_data


# 全局转换器实例
_converter_instance = None

def get_data_converter() -> TabletToStorageConverter:
    """获取数据转换器实例（单例模式）"""
    global _converter_instance
    if _converter_instance is None:
        _converter_instance = TabletToStorageConverter()
    return _converter_instance